/*
 * Copyright (c) 2007 Compl Yue Still, All Rights Reserved.
 */

/**
 * 
 */
package hbi.wire.java.host;

import hbi.task.java.AgentMethodInvocation;
import hbi.wire.ProtocolError;

import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;

class MethodInvocation implements IncomingTag
{

    private final TaskScript script;

    MethodInvocation(TaskScript script)
    {
        this.script = script;
    }

    Method method = null;

    private DataTagList argTags = null;

    public boolean processIncomingData(ByteBuffer buffer) throws IOException
    {
        while (buffer.hasRemaining())
        {
            if (method == null)
            {
                if (buffer.remaining() < 2) return false;
                int methodIndex = buffer.getShort() & 0xFFFF;
                this.method = script.agentType.getResolvedMethod(methodIndex);
                System.err.println("Received invocation: " + method);
                Class<?>[] argTypes = method.getParameterTypes();
                if (argTypes.length < 1)
                {
                    script.invocations.add(new AgentMethodInvocation(method,
                        new Object[0]));
                }
                else
                {
                    argTags = new DataTagList(argTypes);
                }
                if (!buffer.hasRemaining()) return false;
            }

            if (argTags == null)
            {
                int tag = buffer.get() & 0xFF;
                if (tag != 'z')
                    throw new ProtocolError("'z' expected after all arguments.");
                return true;
            }
            else if (argTags.processIncomingData(buffer))
            {
                script.invocations.add(new AgentMethodInvocation(method,
                    (Object[]) argTags.getTagValues()));
                argTags = null;
            }
            else
            {
                break;
            }
        }
        return false;
    }

}
